﻿using System;
using System.Collections.Generic;
using System.Linq;
using Telerik.Web.Mvc.Extensions;

namespace SapaFinance.Domain.Model
{
    public class Corporation : AbstractEntity
    {
        protected Corporation()
        {
            Accounts = new List<Account>();
            Cfos = new List<CFO>();
        }

        public Corporation(User user)
            : this()
        {
            CreatedBy = new Identity(user);
            Change(user);
        }


        public virtual ICollection<Account> Accounts { get; private set; }
        public virtual ICollection<CFO> Cfos { get; set; }
        public virtual string Name { get; set; }
        public virtual Agent Agent { get; private set; }
        public virtual string Description { get; set; }
        public virtual DateTime? RegistrationDate { get; set; }
        public virtual string FullName { get; set; }
        public virtual string LegalAddress { get; set; }
        public virtual string ActualAddress { get; set; }
        public virtual string Tin { get; set; }
        public virtual string Kpp { get; set; }
        public virtual bool IsHidden { get; set; }
        public virtual Identity DeletedBy { get; private set; }
        public virtual string DirectorName { get; set; }
        public virtual string AccountantName { get; set; }
        public virtual Identity CreatedBy { get; private set; }
        public virtual Identity ChangedBy { get; private set; }
        public virtual string Okonh { get; set; }
        public virtual string Okpo { get; set; }
        public virtual bool IsPayer { get; set; }

        public void Visible(CFO cfo)
        {
            if (!Cfos.Contains(cfo))
                Cfos.Add(cfo);
        }

        public void Visible(IEnumerable<CFO> cfos)
        {
            Invisible();
            foreach (var cfo in cfos)
                Visible(cfo);
        }
        public void Change(User user)
        {
            ChangedBy = new Identity(user);
        }
        private void Invisible()
        {
            foreach (var cfo in Cfos.ToList())
                RemoveCfo(cfo);
        }

        public bool RemoveCfo(CFO cfo)
        {
            return Cfos.Remove(cfo);
        }

        public void SetAgent(Agent agent)
        {
            Agent = agent;
        }

        public Account GetPrimaryAccount()
        {
            return Accounts.SingleOrDefault(x => x.IsPrimary);
        }


        public void Delete(User user)
        {
            DeletedBy = new Identity(user);
        }

   
        //public void ClearCompany()
        //{
        //    Agent = null;
        //}

        public void AddAccount(Account account)
        {
            if (account.IsPrimary){
                SetAllAccountsToUnPrimary();
            }
            if (!Accounts.Contains(account)){
                Accounts.Add(account);
            }
        }

        //public List<Account> GetActiveAccounts()
        //{
        //    return Accounts.Where(x => x.IsHidden).ToList();
        //}

        public Account GetAccount(Guid id)
        {
            return Accounts.Where(x => x.UID == id).SingleOrDefault();
        }

        public void ChangeAccount(Account account)
        {
            if (Accounts.Contains(account)){
                Accounts.Remove(account);
                AddAccount(account);
            }
        }

        public void OpenAccount(string number, Currency currency, Bank bank, User user)
        {
            Accounts.Add(new Account(number, currency, bank, this, user));
        }

        public void SetAllAccountsToUnPrimary()
        {
            foreach (var account in Accounts)
                account.SetPrimary(false);
        }

        public override bool Equals(object obj)
        {
            var compare = (Corporation)obj;
            if (ReferenceEquals(null, compare)) return false;
            if (UID != Guid.Empty) return base.Equals(compare);
            return Tin.Equals(compare.Tin);
        }

        public void DeleteAccount(Account account)
        {
            Accounts.Remove(account);
            
        }
    }
}